package org.NooLab.somclients.components;

import java.util.Observable;

import org.NooLab.somclients.components.params.SomClientParamPkgIntf;
import org.NooLab.somclients.domains.ScMTMParamPkg;
import org.NooLab.somclients.domains.ScMTMParamPkgIntf;
import org.NooLab.somclients.domains.ScSomfixParamPkg;
import org.NooLab.somclients.domains.ScSomfixParamPkgIntf;
import org.NooLab.somclients.domains.SomClientIntf;
import org.NooLab.somclients.domains.SomClientParamPkg;
import org.NooLab.somclients.domains.SomClientPublicIntf;
import org.NooLab.somclients.intf.SomClientControlIntf;
import org.NooLab.somclients.intf.SomClientsPublicIntf;
import org.NooLab.utilities.logging.PrintLog;
import org.NooLab.utilities.net.GUID;





/**
 * 
 * 
 * This also maintains a service channel via tcp;
 * 
 * 
 *
 */
public class SomClientsFactory  
								extends
											Observable
								implements 
											SomClientsPublicIntf{

	protected  SomClients somClients;
	protected  SomClientsProperties scsProperties ;
	
	protected  static SomClientsFactory scf ;
	protected  static int startRequest = 0;
	
	
	
	
	
	PrintLog out = new PrintLog(2,false);
	
	// ========================================================================
	protected SomClientsFactory(SomClientsProperties scProps){
		scsProperties = scProps ;
		
		scsProperties.setClientsFactory(this);
		
		new StarterHelper();
	}
	
	/**
	 * returns a perspective (via interface "") that allows to create a ClientParameterPackage,
	 * and to communicate with SomClients
	 * @param scProperties 
	 * 
	 * @return
	 */
	public static SomClientsPublicIntf getInstance(SomClientsPropertiesPublicIntf scprops){
		
		if (scf==null){ // != null ? -> quite necessary in this way to handle affairs...
			            // the constructor of SomClients calls this too!
			SomClientsProperties scProps = new SomClientsProperties (scprops);
			scf = new SomClientsFactory(scProps);
		}
		return scf;
	}
	// ========================================================================	
	
	
	public static SomClientsPropertiesPublicIntf getProperties() {
		return new SomClientsProperties ();
	}
	
	@Override
	public SomClientsPropertiesPublicIntf getScProperties() {
 
		return somClients.scsProperties;
	}

	protected void startSomClients() throws Exception{
	
											out.print(3, "SomClients framework is going to be started...");
		somClients = new SomClients( this, scsProperties);
	}
	
	
	private class StarterHelper implements Runnable{
		
		Thread scsStarterHelperThrd;
		int k=0;
		
		public StarterHelper(){
			scsStarterHelperThrd = new Thread(this,"scsStarterHelperThrd") ; 
			scsStarterHelperThrd.start();
		}
		
		@Override
		public void run() {
			
			try {

				startSomClients();
				
			} catch (Exception e) {
				e.printStackTrace();
			}
			 
		}
		
		
	}
	
	// ----------------------------------------------------
	
	
	@Override
	public Object getParameterPackage(int clientType) {
		
		// the simple story is that we create a interfaced object acc. to the request;
		// this we will return as an object
		// the caller is responsible for the correct mapping..
		
		if (clientType == SomClientIntf._SOMCLIENT_TYPE_SOMDED ){
			
			ScSomfixParamPkg params = new ScSomfixParamPkg() ; 
			return (ScSomfixParamPkgIntf)params;
		}

		if (clientType == SomClientIntf._SOMCLIENT_TYPE_SOMPOP ){

			return null;
		}

		if (clientType == SomClientIntf._SOMCLIENT_TYPE_MARKOVTABLE ){

			ScMTMParamPkg params = new ScMTMParamPkg() ; 
			return (ScMTMParamPkgIntf)params;
		}

		if (clientType == SomClientIntf._SOMCLIENT_TYPE_MARKOVHMM ){
			
			return null;
		}

		if (clientType == SomClientIntf._SOMCLIENT_TYPE_SPELA ){
			
			return null;
		}

		if (clientType == SomClientIntf._SOMCLIENT_TYPE_DISPLAY ){
			
			return null;
		}

		if (clientType == SomClientIntf._SOMCLIENT_TYPE_QUERY ){
			
			return null;
		}

		 
		
		return null;
	}

	@Override
	public SomClientParamPkgIntf getParameterPackage(){
		// this acts as a facade to SomClients
		
		String guid = GUID.randomvalue() ;
		
		return getParameterPackage(guid);
	}
	
	@Override
	public SomClientParamPkgIntf getParameterPackage(String guidIn){
		// this acts as a facade to SomClients
		SomClientParamPkg pp = new SomClientParamPkg();
		return pp;
	}
	
	
	/**
	 * 
	 * this actually creates a SomClient, or reloads a hibernated one...
	 */
	@Override
	public String operateParameters( SomClientParamPkgIntf paramsPkg){
		
		String guid = GUID.randomvalue() ;
		
		// the queue for this is in  SomClients::SCliAssimilator::run()
		somClients.waitingPackages.add(paramsPkg);
		paramsPkg.setGuid( guid);
		
		return guid;
	}
	
	@Override
	public SomClientStateDescription getStateOfSomClient( String byThisGuid){
		
		
		return somClients.getStateOfSomClient( byThisGuid);
	}
	
	@Override
	public void setControlToSomClient(SomClientControlIntf control){
		somClients.setControlToSomClient( control); 
	}
	
	@Override
	public SomClientPublicIntf getSomClient(String guid){
		return somClients.getSomClient( guid );
	}

	

	
}
